import { inject } from '@loopback/core';
import {
  Request,
  RestBindings,
  get,
  response,
  Response,
  ResponseObject,
  HttpErrors,
} from '@loopback/rest';
import { readFileSync } from 'fs';
import { container } from '../inversify.config.report';
import { PagePoolImpl } from '../services/page.management.sevice';
import path from 'path'
const pagePool = container.get(PagePoolImpl)
declare function generateProposal(
  jsonTemplate: string,
  dsparam: string,
): Promise<string>;
function generatePDFInBrowser(jsonTemplate: string, dsparam: string) {
  return generateProposal(jsonTemplate, dsparam);
}
declare function generateHtml(
  jsonTemplate: string,
  dsparam: string,
): Promise<string>;
function generateHTMLInBrowser(jsonTemplate: string, dsparam: string) {
  return generateHtml(jsonTemplate, dsparam);
}
/**
 * OpenAPI response for ping()
 */
const PING_RESPONSE: ResponseObject = {
  description: 'Ping Response',
  content: {
    'application/json': {
      schema: {
        type: 'object',
        title: 'PingResponse',
        properties: {
          greeting: { type: 'string' },
          date: { type: 'string' },
          url: { type: 'string' },
          headers: {
            type: 'object',
            properties: {
              'Content-Type': { type: 'string' },
            },
            additionalProperties: true,
          },
        },
      },
    },
  },
};

/**
 * A simple controller to bounce back http requests
 */
export class PingController {
  constructor(@inject(RestBindings.Http.REQUEST) private req: Request, @inject(RestBindings.Http.RESPONSE) private res: Response) { }

  // Map to `GET /ping`
  @get('/ping')
  @response(200, PING_RESPONSE)
  ping(): object {
    // Reply with a greeting, the current time, the url, and request headers
    return {
      greeting: 'Hello from LoopBack',
      date: new Date(),
      url: this.req.url,
      headers: Object.assign({}, this.req.headers),
    };
  }


  @get('/pdf')
  async pdf() {
    this.req.setTimeout(0);
    const page = await pagePool.getPage();
    try {
      const start = Date.now();
      const data = await page.evaluate(
        generatePDFInBrowser,
        `static/templates/main.rdlx-json`,
        readFileSync(
          path.join(__dirname, '..', '..', 'public', 'datasource.json'),
          'utf-8',
        ),
      );
      const end = Date.now();
      const pdf = base64ToUint8(data);
      this.res.status(200).contentType('application/pdf').send(pdf);
    } catch (e) {
      throw new HttpErrors.InternalServerError(e);
    } finally {
      pagePool.releasePage(page);
    }
  }
}
function base64ToUint8(data: string): Buffer | null {
  const arr = data.split(',');
  if (arr.length < 2) {
    return null;
  }
  return Buffer.from(arr[1], 'base64');
}